<template>
  <div>
    <el-card>
      <el-form inline>
        <el-form-item>
          <el-input v-model="paramsState.username" placeholder="用户名" />
        </el-form-item>

        <el-button type="primary" icon="el-icon-search" @click="search"
          >查询</el-button
        >
        <el-button type="default" @click="resetSearch">清空</el-button>
      </el-form>

      <div style="margin: 20px 0">
        <el-button type="primary" @click="showAddUser">添 加</el-button>
        <el-button
          type="danger"
          @click="revomveUsers"
          :disabled="tableState.selectedIds.length === 0"
          >批量删除</el-button
        >
      </div>

      <el-table
        border
        stripe
        v-loading="listLoading"
        :data="tableState.users"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />

        <el-table-column type="index" label="序号" width="80" align="center" />

        <el-table-column prop="username" label="用户名" width="150" />
        <el-table-column prop="nickName" label="用户昵称" />
        <el-table-column prop="roleName" label="角色列表" width="200" />

        <el-table-column prop="gmtCreate" label="创建时间" width="180" />
        <el-table-column prop="gmtModified" label="更新时间" width="180" />

        <el-table-column label="操作" width="200" align="center" fixed="right">
          <template slot-scope="{ row }">
            <el-button
              type="info"
              size="small"
              icon="el-icon-user"
              title="分配角色"
              @click="showAssignRole(row)"
            />
            <el-button
              type="primary"
              size="small"
              icon="el-icon-edit"
              title="修改用户"
              @click="showUpdateUser(row)"
            />

            <el-button
              @click="removeUser(row.id)"
              style="margin-left: 10px"
              type="danger"
              size="small"
              icon="el-icon-delete"
              title="删除用户"
            ></el-button>
          </template>
        </el-table-column>
      </el-table>

      <el-pagination
        :current-page="paramsState.page"
        :page-size="paramsState.limit"
        :total="tableState.total"
        :page-sizes="[5, 10, 20, 30]"
        style="padding: 20px 0"
        layout="prev, pager, next, jumper, ->, sizes, total"
        @current-change="getUsers"
        @size-change="getUsers(1, $event)"
      />

      <el-dialog
        :title="userState.user.id ? '修改用户' : '添加用户'"
        :visible.sync="userState.dialogUserVisible"
      >
        <el-form
          ref="userFormRef"
          :model="userState.user"
          :rules="userRules"
          label-width="120px"
        >
          <el-form-item label="用户名" prop="username">
            <el-input v-model="userState.user.username" />
          </el-form-item>
          <el-form-item label="用户昵称">
            <el-input v-model="userState.user.nickName" />
          </el-form-item>

          <el-form-item
            v-if="!userState.user.id"
            label="用户密码"
            prop="password"
          >
            <el-input v-model="userState.user.password" />
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button
            :loading="userState.userLoading"
            type="primary"
            @click="addOrUpdate"
            >确 定</el-button
          >
        </div>
      </el-dialog>

      <el-dialog
        title="设置角色"
        :visible="roleState.dialogRoleVisible"
        :before-close="resetRoleData"
      >
        <el-form label-width="80px">
          <el-form-item label="用户名">
            <el-input disabled :value="userState.user.username"></el-input>
          </el-form-item>

          <el-form-item label="角色列表">
            <el-checkbox
              :indeterminate="roleState.isIndeterminate"
              v-model="roleState.checkAll"
              @change="handleCheckAllChange"
              >全选</el-checkbox
            >
            <div style="margin: 15px 0"></div>
            <el-checkbox-group
              v-model="roleState.userRoleIds"
              @change="handleCheckedChange"
            >
              <el-checkbox
                v-for="role in roleState.allRoles"
                :key="role.id"
                :label="role.id"
                >{{ role.roleName }}</el-checkbox
              >
            </el-checkbox-group>
          </el-form-item>
        </el-form>

        <div slot="footer">
          <el-button
            :loading="roleState.roleLoading"
            type="primary"
            @click="assignRole"
            >保存</el-button
          >
          <el-button @click="resetRoleData">取消</el-button>
        </div>
      </el-dialog>
    </el-card>
  </div>
</template>

<script>
import {
  assignUserRoleListApi,
  getUserRoleListApi,
  removeUsersApi,
  removeUserApi,
  getUserListApi,
  saveOrUpdateUserApi,
} from "@/api/acl/userCommand";
export default {
  name: "userCommand",

  data() {
    return {
      listLoading: false,
      paramsState: {
        username: "",
        searchUsername: "",
        page: 1, // 当前页码
        limit: 5, // 每页数量
      },
      tableState: {
        total: 0,
        users: [],
        selectedIds: [],
      },
      userRules: {
        username: [
          { required: true, message: "用户名必须输入" },
          { min: 4, message: "用户名不能小于4位" },
        ],
        password: [{ required: true, validator: this.validatePassword }],
      },
      userState: {
        dialogUserVisible: false,
        userLoading: false,
        user: {
          username: "",
          nickName: "",
          password: "",
        },
      },
      roleState: {
        dialogRoleVisible: false,
        roleLoading: false,
        checkAll: false,
        isIndeterminate: false,
        userRoleIds: [],
        allRoles: [],
      },
    };
  },

  mounted() {
    this.getUsers();
  },

  methods: {
    // 密码校验
    validatePassword(rule, value, callback) {
      if (!value) {
        callback("密码必须输入");
      } else if (!value || value.length < 6) {
        callback("密码不能小于6位");
      } else {
        callback();
      }
    },

    /*
  显示指定角色的界面
  */
    showAssignRole(user) {
      this.userState.user = user;
      this.roleState.dialogRoleVisible = true;
      this.getRoles();
    },

    /*
  全选勾选状态发生改变的监听
  */
    handleCheckAllChange(value) {
      // value 当前勾选状态true/false
      // 如果当前全选, userRoleIds就是所有角色id的数组, 否则是空数组
      this.roleState.userRoleIds = value
        ? this.roleState.allRoles.map((item) => item.id)
        : [];
      // 如果当前不是全选也不全不选时, 指定为false
      this.roleState.isIndeterminate = false;
    },
    /*
  异步获取用户的角色列表
  */
    async getRoles() {
      const result = await getUserRoleListApi(this.userState.user?.id);
      const { allRolesList, assignRoles } = result.data;
      this.roleState.allRoles = allRolesList;
      this.roleState.userRoleIds = assignRoles.map((item) => item.id);

      this.roleState.checkAll = allRolesList.length === assignRoles.length;
      this.roleState.isIndeterminate =
        assignRoles.length > 0 && assignRoles.length < allRolesList.length;
    },

    /*
  角色列表选中项发生改变的监听
  */
    handleCheckedChange() {
      const { userRoleIds, allRoles } = this.roleState;
      this.roleState.checkAll =
        userRoleIds.length === allRoles.length && allRoles.length > 0;
      this.roleState.isIndeterminate =
        userRoleIds.length > 0 && userRoleIds.length < allRoles.length;
    },

    /*
  请求给用户进行角色授权
  */
    async assignRole() {
      const userId = this.userState.user?.id;
      const roleIds = this.roleState.userRoleIds.join(",");
      this.roleState.roleLoading = true;
      await assignUserRoleListApi(userId, roleIds);
      this.roleState.roleLoading = false;
      this.$message.success("分配角色成功");
      this.resetRoleData();
    },

    /*
  重置用户角色的数据
  */
    async resetRoleData() {
      Object.assign(this.roleState, {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false,
      });
      // 重新获取数据
      await this.getUsers();
    },

    /*
  根据输入进行搜索
  */
    search() {
      this.paramsState.searchUsername = this.paramsState.username;
      this.getUsers(1);
    },

    /*
  重置输入后搜索
  */
    resetSearch() {
      this.paramsState.searchUsername = "";
      this.paramsState.username = "";
      this.getUsers(1);
    },

    /*
  显示添加用户的界面
  */
    showAddUser() {
      this.userState.user = {
        username: "",
        nickName: "",
        password: "",
      };
      this.userState.dialogUserVisible = true;

      this.$nextTick(() => this.$refs.userFormRef.value?.clearValidate());
    },

    /*
  删除所有选中的用户
  */
    revomveUsers() {
      this.$confirm("确定删除吗?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        callback: async (action) => {
          if (action == "confirm") {
            await removeUsersApi(this.tableState.selectedIds);
            this.$message.success("删除成功");
            this.getUsers();
          }
        },
      });
    },

    /*
  列表选中状态发生改变的监听回调
  */
    handleSelectionChange(selection) {
      this.tableState.selectedIds = selection.map((item) => item.id);
    },

    /*
  显示更新用户的界面
  */
    showUpdateUser(user) {
      this.userState.user = { ...user };
      this.userState.dialogUserVisible = true;
    },

    /*
  删除某个用户
  */
    async removeUser(id) {
      this.$confirm("是否要删除", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        callback: async (action) => {
          if (action == "confirm") {
            await removeUserApi(id);
            this.$message.success("删除成功");
            this.getUsers(
              this.tableState.users.length === 1
                ? this.paramsState.page - 1
                : this.paramsState.page
            );
          }
        },
      });
    },

    /*
  获取分页列表
  */
    async getUsers(
      page = this.paramsState.page,
      limit = this.paramsState.limit
    ) {
      this.paramsState.page = page;
      this.paramsState.limit = limit;
      this.listLoading = true;
      const result = await getUserListApi(page, limit, {
        username: this.paramsState.searchUsername,
      });
      this.listLoading = false;
      const { items, total } = result.data;
      this.tableState.users = items;
      this.tableState.total = total;
      this.tableState.selectedIds = [];
    },
    /*
  取消用户的保存或更新
  */
    cancel() {
      this.userState.dialogUserVisible = false;
      this.userState.user = {
        username: "",
        nickName: "",
        password: "",
      };
    },

    /*
  保存或者更新用户
  */
    async addOrUpdate() {
      // 进行表单校验
      await this.$refs.userFormRef.value?.validate();

      const { user } = this.userState;
      if (user.username === "admin") {
        alert("admin账号不能添加或更新");
        return;
      }
      this.userState.userLoading = true;
      try {
        await saveOrUpdateUserApi(user);
        this.userState.userLoading = false;
        this.$message.success("保存成功!");
        this.getUsers(user.id ? this.paramsState.page : 1);
        this.userState.user = {
          username: "",
          nickName: "",
          password: "",
        };
        this.userState.dialogUserVisible = false;
      } catch (error) {
        this.userState.userLoading = false;
      }
    },
  },
};
</script>

<style lang="scss" scoped></style>
